﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using LeoGemini.Service.Infrastructure.Handler.Exception;
using Newtonsoft.Json;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Localization.VirtualFiles;

namespace GoodsService.Domain.Aggregate.Goods
{
    /// <summary>
    /// Sku聚合根
    /// </summary>
    [Table("tb_goods_sku")]
    public class GoodsSku : Entity<Guid>, IHasCreationTime
    {
        /// <summary>
        /// ORM框架使用
        /// </summary>
        protected GoodsSku() { }

        internal GoodsSku(Guid id)
        {
            Id = id;
            Specs = new List<GoodsSpec>();
        }

        public GoodsSku(Guid id, decimal price, int stock, string unit, bool isShowStock) : this(id)
        {
            Price = CostPrice = price;
            Stock = stock;
            Unit = unit;
            IsShowStock = isShowStock;
        }

        /// <summary>
        /// 所属商品id
        /// </summary>
        [Column("reference_goods_id")]
        public virtual string ReferenceGoodsId { get; private set; }

        /// <summary>
        /// 现价
        /// </summary>
        [Column("price")]
        public virtual decimal Price { get; private set; }
        
        /// <summary>
        /// 原价
        /// </summary>
        [Column("cost_price")]
        public virtual decimal CostPrice { get; private set; }
        
        /// <summary>
        /// 库存数量
        /// </summary>
        [Column("stock")]
        public virtual int Stock { get; private set; }
        
        /// <summary>
        /// 库存单位
        /// </summary>
        [Column("unit")]
        public virtual string Unit { get; private set; }
        
        /// <summary>
        /// 是否显示库存
        /// </summary>
        [Column("is_show_stock")]
        public virtual bool IsShowStock { get; private set; }
        
        /// <summary>
        /// Sku属性
        /// </summary>
        public virtual ICollection<GoodsSpec> Specs { get; private set; }
        
        public virtual DateTime CreationTime { get; set; }
        
        [JsonIgnore]
        public virtual Goods Goods { get; private set; }

        /// <summary>
        /// 标记属性值
        /// </summary>
        public void MarkSpec(string specType, string specValue)
        {
            if (Specs.Any(s => s.SpecType == specType && s.SpecValue == specValue))
                throw new ConflictException(ErrorMessage.GOODS_SPEC_CONFLICT);
            Specs.Add(new GoodsSpec(specType, specValue));
        }

        /// <summary>
        /// 解除标记属性值
        /// </summary>
        public void UnMarkSpec(string specType, string specValue)
        {
            var spec = Specs.First(s => s.SpecType == specType && s.SpecValue == specValue);
            Specs.Remove(spec);
        }
    }
}